;   This program is free software: you can redistribute it and/or modify
;   it under the terms of the GNU General Public License as published by
;   the Free Software Foundation, either version 3 of the License, or
;   (at your option) any later version.
;
;   This program is distributed in the hope that it will be useful,
;   but WITHOUT ANY WARRANTY; without even the implied warranty of
;   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
;   GNU General Public License for more details.
;
;   You should have received a copy of the GNU General Public License
;   along with this program.  If not, see <http://www.gnu.org/licenses/>.
;
;程序名称:house.asm
;功能:益智游戏
;环境:16BIT DOS实模式(windows/dos或dosbox)最好全屏
;编译器:MASM 5.1-6X (这个是com格式，masm5.x须用EXE2BIN 4CHESS.EXE 4CHESS.COM，Masm6.x须加入：ml /ＡＴ参数
;用法:看说明
;返回值:没有
;破坏寄存器:不适用
;
;Q.http://tieba.baidu.com/p/3873497011
;一、益智游戏
;猜猜房子里有几个人：随机出现M个人从左边进入房子，随机N 个人从右边离开房子
;一段时间后，输入房子中的人数。系统判断是否正确。
;要求：人物和房子用图形方式实现
;
;解:
;当然仍是文字模式，不会真的这么闲去做图形显示，
;随便做些小人，时钟和火炬，意思一下算了．．．
;小人随机进入，随机离开，等一段时间询问屋里有多少人数？
;答对了Win，答错了lost
;
;注意:这只是一个范例程式，具备最起码的功能，没有太花巧的技术
;若你需要其他功能或加入或删减任何代码，请随便，但不能要求作者为你订制特定的功能或
;根据功课要求而改变这个子程序改变那个子程序，若是代码错误或优化代码的意见，
;则欢迎提出:)
;
;因为没多少空闲，程序只加了一些简单解释。
;
;代码及程式
;http://pan.baidu.com/s/1hqldS7i
;
;
.286
star_color      equ     0Eh
man_color       equ     04h
ask_color       equ     0Ah
win_color       equ     9eh
lost_color      equ     9fh
pic1_back_color equ     07h
clock_color     equ     0eh
light_color     equ     0Fh
start1_x        equ     35
start1_y        equ     1
ask_x           equ     24
ask_y           equ     1
win_x           equ     22
win_y           equ     10
time_delay      equ     1 * 5 ;  ? sec
clock_limit     equ     18
byte_NO     equ	128
clock1_x        equ     16
clock1_y        equ     12
clock2_x        equ     62
clock2_y        equ     12
char_table_l    equ     35
light1_x        equ     30
light1_y        equ     8
light2_x        equ     48
light2_y        equ     8

@GetCur		MACRO	page
		IFNB	<page>
		mov	bh,page
		ELSE
		xor	bh,bh
		ENDIF
		mov	ah,03h
		int	10h
		ENDM
; 02h
@SetCurPos	MACRO	column,row,page
		IFNB	<column>
		mov	dl,column
		ENDIF
		IFNB	<row>
		mov	dh,row
		ENDIF
		IFNB	<page>
		mov	bh,page
		ELSE
		xor	bh,bh
		ENDIF
		mov	ah,02h
		int	10h
		ENDM
; 01h
@SetCurSz	MACRO	first,last
		mov	ch,first
		mov	cl,last
		mov	ah,01h
		int	10h
		ENDM
; 08h
@GetChAtr	MACRO	page
		IFNB	<page>
		mov	bh,page
		ELSE
		sub	bh,bh
		ENDIF
		mov	ah,08h
		int	10h
		ENDM
; 09h
@PutChAtr	MACRO	char,atrib,page,repeat
		IFNB	<char>
		mov	al,char
		ENDIF
		IFNB	<atrib>
		mov	bl,atrib
		ENDIF
		IFNB	<page>
		mov	bh,page
		ELSE
		xor	bh,bh
		ENDIF
		IFNB	<repeat>
		mov	cx,repeat
		ELSE
		mov	cx,1
		ENDIF
		mov	ah,09h
		int	10h
		ENDM

COD             segment
                assume  cs:cod, ds:cod,es:cod
                org     100h
start:          jmp     begin

pic1_data        label   byte
db '                                                                                '
db '   ',250,'                                                                            '
db '                                      .-.                           ',250,'           '
db '                                     /___\                                      '
db '                                     |___|                                      '
db '            ',250,'                        |]_[|         ',250,'                            '
db '                                     / I \                                      '
db '                                  JL/  |  \JL                                   '
db '       .-.                    i   ()   |   ()   i                    .-.        '
db '       |_|     .^.           /_\  LJ=======LJ  /_\           .^.     |_|        '
db ' _._._/___\._./___\_._._._._.L_J_/.-. .-. .-.\_L_J._._._._._/___\._./___\._._._ '
db ' .,        ., |-,-| .,       L_J  |_| [I] |_|  L_J       ., |-,-| .,        .,  '
db ' JL        JL |-?| JL       L_J%%%%%%%%%%%%%%%L_J       JL |-?| JL        JL  '
db " HH_IIIIII_HH_'-'-'_HH_IIIIII|_|=======H=======|_|IIIIII_HH_'-'-'_HH_IIIIII_HH_ "
db ' []--------[]-------[]-------[_]----\.=I=./----[_]-------[]-------[]--------[]- '
db ' ||  _/\_  ||\\_I_//||  _/\_ [_] []_/_L_J_\_[] [_] _/\_  ||\\_I_//||  _/\_  ||\ '
db ' ||  |__|  ||=/_|_\=||  |__|_|_|   _L_L_J_J_   |_|_|__|  ||=/_|_\=||  |__|  ||- '
db ' ||  |__|  |||__|__|||  |__[___]__--__===__--__[___]__|  |||__|__|||  |__|  ||| '
db ' [_]IIIIIII[_]IIIII[_]IIIIIL___J__II__|_|__II__L___JIIIII[_]IIIII[_]IIIIIIII[_] '
db ' [_] \_I_/ [_]\_I_/[_] \_I_[_]\II/[]\_\I/_/[]\II/[_]_I_/ [_]\_I_/[_] \_I_/  [_] '
db ' L_J./   \.L_J/   \L_J./   L_JI  I[]/     \[]I  IL_J   \.L_J/   \L_J./   \. L_J '
db ' L_J|     |L_J|   |L_J|    L_J|  |[]|     |[]|  |L_J    |L_J|   |L_J|     | L_J '
db ' L_JL_____JL_JL___JL_JL____|-||__|[]|__',138,139,'_|[]|__||-|____JL_JL___JL_JL__',138,139,'_J_L_J '
db '                                                                                '
pic_data_L      equ     $ - offset pic1_data

man_data label byte
db 134,20h,135,135,20h,134,20h,134,20h,135,20h,134,20h,20h,135,20h,134,134
db 20h,20h,134,135,20h,134,20h,20h,135,20h,134,20h,20h,135,20h,134,20h
db 135,20h,20h,134,20h,135,20h,20h,134,20h,20h,135,20h,134,20h,135,20h,134
db 20h,20h,135,20h,20h,134,20h,20h,135,135,134,134,20h,135,135,20h,134
db 135,20h,134,20h,135,134,134,20h,135,20h,20h,20h,134,20h,20h,20h
db 135,20h,20h,134,20h,135,20h,134,20h,20h,135,20h,134,20h,135,20h
db 134,20h,135,135,134,20h,135,20h,134,134,135,20h,134,20h,135,20h,20h,134
last_man db 135, 40 dup (20h)

last_add        dw      offset last_man
clock_char      db      144,145
clock_add       db      clock1_x,clock1_y,clock2_x,clock2_y
clock_flag      dw      0
light_char      db      140,141
light_add       db      light1_x,light1_y,light2_x,light2_y
ask_str         db      'How many people in this house? '
ask_str_L       equ     $ - offset ask_str
win_str         db      '           You are Win !!!         '
win_str_L       equ     $ - offset win_str
lost_str        db      'You are Lost, total people are:'
man_count_num   db      5 dup (20h)
lost_str_L      equ     $ - offset lost_str
man_count       dw      0
user_count      dw      0

face1           dd      4 dup (0,0,0,0,0,0)
right1          db      00000000b
                db      00111100b
                db      01111010b
                db      01110010b
                db      00111100b
                db      01000010b
                db      01011010b
                db      01011010b
                db      01011111b
                db      01000010b
                db      01111110b
                db      00111100b
                db      00110110b
                db      01100110b
                db      01100011b
                db      11000011b

right2          db      00000000b
                db      01111100b
                db      01111010b
                db      01110010b
                db      00111100b
                db      00100010b
                db      11110010b
                db      10100110b
                db      10101011b
                db      10100010b
                db      00111110b
                db      00111100b
                db      00110110b
                db      01100110b
                db      01101100b
                db      01101110b
                dd      4 dup (0,0)

door1           db      11111111b
                db      10000100b
                db      11111111b
                db      10100000b
                db      10100000b
                db      10100000b
                db      10100000b
                db      10100000b
                db      10100110b
                db      10100110b
                db      10100000b
                db      10100000b
                db      10100000b
                db      10100000b
                db      10100000b
                db      11111111b

door2           db      11111111b
                db      00100001b
                db      11111111b
                db      00000101b
                db      00000101b
                db      00000101b
                db      00000101b
                db      00000101b
                db      01100101b
                db      01100101b
                db      00000101b
                db      00000101b
                db      00000101b
                db      00000101b
                db      00000101b
                db      11111111b

light1          db      00100100b
                db      10011001b
                db      01100110b
                db      01100110b
                db      11011011b
                db      11011011b
                db      01100110b
                db      01100110b
                db      01111110b
                db      10011001b
                db      01011010b
                db      00011000b
                db      00011000b
                db      00011000b
                db      00011000b
                db      00011000b

light2          db      00000000b
                db      00011000b
                db      00100100b
                db      00100100b
                db      01010010b
                db      01001010b
                db      00100100b
                db      00100100b
                db      00111100b
                db      00011000b
                db      00011000b
                db      00011000b
                db      00011000b
                db      00011000b
                db      00011000b
                db      00011000b
                dd      4 dup (0,0)

clock1          db      11111111b
                db      10011001b
                db      10100101b
                db      11001011b
                db      11010011b
                db      10100101b
                db      10011001b
                db      10000001b
                db      11111111b
                db      10011001b
                db      10010001b
                db      10100001b
                db      11000001b
                db      11000001b
                db      10000001b
                db      11111111b

clock2          db      11111111b
                db      10011001b
                db      10100101b
                db      11001011b
                db      11010011b
                db      10100101b
                db      10011001b
                db      10000001b
                db      11111111b
                db      10011001b
                db      10001001b
                db      10000101b
                db      10000011b
                db      10000011b
                db      10000001b
                db      11111111b
                dd      4 * 17 dup (0)
;char_table_l    equ     ($ - offset char_table)
color           db      0
color_flag      db      1
leave_flag      db      0
old_time	dw	0
clock_init      dd      0
clock_count	dw	0
clock_count1    dw      0
back_color      db      0
delay_count     dw      0
leave_count     dw      0
leave_count1    dw      0
time_up         db      0
name_L          dw      6 ;------------
exit_flag       db      0
attrib          db      7,0
cur_size        dw      0
cur_pos         dw      0
rows            db      24
cols            db      80
pic_add_table   label   byte
                dw      offset pic1_data,start1_x,start1_y,pic1_back_color
                ;       (pic offset), start position, color
pic_add_L       equ     ($ - offset pic_add_table) / 2
;-------------------------------------------------------------------------------
begin:          mov     ax,cs
                mov     ds,ax
                mov     es,ax
                cld
                call    get_old_time
j120:           call    cls
j125:           mov     bx,offset pic_add_table

j127:           mov     si,[bx]
                ;mov     al,[bx+2]
                ;mov     msg_x,al
                ;mov     al,[bx+4]
                ;mov     msg_y,al
                mov     al,[bx+6]
                mov     back_color,al
                ;
                mov     ax,0b800h
                mov     es,ax
                mov     cx,pic_data_L
                xor     di,di
go05:
                lodsb
                mov     ah,back_color
                cmp     al,250
                jnz     go07
                mov     ah,star_color
go07:
                stosw
                loop    go05
                push    cs
                pop     es
                @SetCurSz 30h,31h              ;hidden cursor
                call    set_font

restart:        mov     ah,1                   ;keyboard
                int     16h
                jz      re5
                mov     ah,0
                int     16h
                cmp     al,1bh                 ;press <esc>
                jnz     re5
                jmp     quit

re5:            call    Time_check
                jnc     restart
                call    print_man
                jmp     short restart

quit:           call    cls
                mov     ah,4ch                 ;end program
                int     21h
;----------------------------------------------------------------------------------
print_man:      @SetCurPos 0,23
                mov     bp,40
		mov	si,last_add
                mov     bl,man_color
                call    print_color
                cmp     al,20h  ;space
                jz      printm10
                inc     man_count
printm10:
                cmp     leave_flag,2
                jnz     printm20
                ;       time_up
                @SetCurPos 72,23

printm15:       call    out_256_rand
                cmp     ax,250
                ja      printm15
                mov     si,25
                mov     dx,0
                mov     ah,0
                div     si
                mov     bp,8
		mov	si,last_add
                add     si,ax
		mov	bl,man_color
                push    si
                call    print_color
                pop     si
                cmp     byte ptr [si],20h  ;space
                jz      printm20
                dec     man_count
printm20:       call    print_clock
                ret
;----------------------------------------------------------------------------------
print_clock:    @SetCurPos clock1_x,clock1_y
                mov     si,offset clock_char
                add     si,clock_flag
                mov     bp,1
                mov     bl,clock_color
                push    si
                call    print_color
                pop     si
                @SetCurPos clock2_x,clock2_y
                mov     bp,1
                mov     bl,clock_color
                call    print_color

                @SetCurPos light1_x,light1_y
                mov     si,offset light_char
                add     si,clock_flag
                mov     bp,1
                mov     bl,light_color
                push    si
                call    print_color
                pop     si
                @SetCurPos light2_x,light2_y
                mov     bp,1
                mov     bl,light_color
                call    print_color
                ret
;----------------------------------------------------------------------------------
print_color:    ;si = offset , bp = count , bl=color
		mov ah,3
		mov bh,0
		int 10h ;get cursor position
re_print:
		push dx ;save it
		lodsb
		mov ah,9
		mov bh,0
		mov cx,1
                ;mov bl,man_color
		int 10h  ;print 1 bytes with red color
		pop dx	;restore cursor position
		inc dl	; forward 1 byte
		mov bh,0
		mov ah,2 ;get new cursor position
		int 10h
		dec bp	;next bytes
		jnz re_print
		ret
;----------------------------------------------------------------------------------
cls:            mov     ax,0003h
                int     10h
                ret
;------------------------------------------------------------------------------
Time_check:	push	es
                mov     time_up,0
                mov     ax,40h
                mov     es,ax
                mov     ax,es:[006ch] ;get system time count
                cmp     ax,old_time
                jnz     time_2
                jmp     time_checkx
time_2:
                mov     old_time,ax
                cmp     leave_flag,1
                jb      time_10
                jz      time_8
                dec     leave_count1
                jnz     time_10
                ;       ask time up
                call    ask_proc

time_8:         dec     leave_count
                jnz     time_10
                mov     leave_flag,2
                inc     time_up

time_10:        inc     clock_count1
                cmp     clock_count1,clock_limit ;18
                jb      time_20
                mov     clock_count1,0
                xor     clock_flag,1
                inc     time_up

time_20:        inc     Clock_count             ;no check, direct draw
                cmp     Clock_count,time_delay  ;10x18
                jb      time_check20
                inc     time_up
                mov     Clock_count,0           ;no check, direct draw
                dec     last_add
		cmp	last_add,offset man_data
		jae	Time_check20
time_30:        mov     last_add,offset man_data + 40
                ;       start man exit
time_40:        call    out_256_rand   ;return al (0-255)
                xor     ah,ah
                add     ax,18 * 1       ;2 seconds
                cmp     ax,40
                ja      time_40         ;2 - 8 second
                mov     leave_count,ax
time_50:        call    out_256_rand   ;return al (0-255)
                xor     ah,ah
                add     ax,98
                cmp     ax,210
                ja      time_50
                mov     leave_count1,ax
                mov     leave_flag,1
Time_check20:   cmp     time_up,0
                jz      time_checkx
                stc
		jmp	short Time_checkxx
Time_checkx:	clc
Time_checkxx:	pop	es
		ret
;---------------------------------------------------------
ask_proc:       @SetCurPos ask_x,ask_y
                mov     bp,ask_str_L
                mov     si,offset ask_str
                mov     bl,ask_color
                call    print_color
                @SetCurSz 0ch,0dh       ;open cursor
                mov     bx,0
                mov     cx,3
                mov     bp,10
ask_10:
                mov     ah,7
                int     21h
                cmp     al,0dh
                jz      ask_20
                cmp     al,'0'
                jb      ask_10
                cmp     al,'9'
                ja      ask_10
                int     29h
                sub     al,'0'
                mov     ah,0
                xchg    bx,ax
                mul     bp
                add     bx,ax
                loop    ask_10
                ;       get ans.
ask_20:         push    cs
                pop     es
                mov     user_count,bx
                mov     ax,man_count
                mov     di,offset man_count_num
                call    print_ax
                mov     si,offset win_str
                mov     bp,win_str_L
                mov     ax,user_count
                dec     man_count ;ajust first door, last man no entry
                cmp     ax,man_count
                jz      ask_30
                mov     si,offset lost_str
                mov     bp,lost_str_L
ask_30:         @SetCurPos win_x,win_y
                mov     bl,win_color
                call    print_color
                ;
                mov     ah,7
                int     21h
                call    quit
                ret
;---------------------------------------------------------
get_old_time:   push    ax
                push    es
                mov     ax,40h
                mov     es,ax
.386
                mov     eax,es:[006ch] ;get system time count
		mov	clock_init,eax
.286
                mov     old_time,ax
		pop	es
                pop     ax
                ret
;--------------------------------------------------------
set_font:       xor     bh,bh                   ;0 - 7:vga,  0 - 4:ega
                mov     ax,1130h                ;get information
                int     10h                     ;cx=no. of byte,dx=screen.Row-1
                push    cs
                pop     es
                mov     bh,cl
                xor     bl,bl                   ;no of display area 0-7
                mov     cx,char_table_l         ;how many byte
                mov     dx,byte_NO              ;start at 0 .. 255
                mov     ax,1100h                ;call ah=11, al=0
                mov     bp,offset face1
                int     10h
                ret
;------------------------------------------------------------------------------
out_256_rand: ;return al (0-255)
                push    ds
                push    bx
                push    dx
                push    cx
                mov     ax,0h
                out     43h,al
                in      al,40h
                in      al,40h
                push    ax
                mov     dx,0
                mov     bx,0
out10:
                mov     ds,bx
                mov     si,0
                mov     cx,0ffffh
out20:
                lodsb
                add     dl,al
                ;xor    dl,al
                loop    out20
                add     bx,1000h ;next segment
                cmp     bx,2000h
                jb      out10
                pop     ax
                xor     ax,dx
                pop     cx
                pop     dx
                pop     bx
                pop     ds
                ret
;--------------------------------
print_AX:       mov     cx,0 ;清0
                mov     bx,10 ;除法準備
Pax1:
                mov     dx,0 ;清0
                div     bx ;ax /10 ,若1234 ,除10後,dl得餘數4,
                push    dx ;保存, ax=1234,依次保存4,3,2,1
                inc     cx ;累加個數
                or      ax,ax ;是否已除盡
                jnz     Pax1 ;不是,再除
                mov     bl,cl ;存個數
Pax2:
                pop     ax  ;後入先出,先印出第一數,然後第二....
                or      al,30h ;轉ascii
                stosb           ;存入字串緩衝
                loop Pax2 ;下一個
                ret
;----------------------
                cod ends
                end start